package org.jeecg.modules.awpay.service.Impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.awpay.common.request.*;
import org.jeecg.modules.awpay.common.result.*;
import org.jeecg.modules.awpay.dao.entity.*;
import org.jeecg.modules.awpay.dao.mapper.PayOrderMapper;
import org.jeecg.modules.awpay.dao.mapper.WxPayInfoMapper;
import org.jeecg.modules.awpay.service.WeiXinPayService;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.jeecg.modules.gwcjava.jiekou.entity.WxOrderStatus;
import org.jeecg.modules.gwcjava.jiekou.mapper.BusinessLogicMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Random;


@Service
public class WeiXinPayServiceImpl implements WeiXinPayService {
    @Resource
    private WxPayInfoMapper wxPayInfoMapper;
    @Resource
    private PayOrderMapper payOrderMapper;

    //逻辑
    @Autowired
    private BusinessLogicMapper logicMapper;


    @Override
    public Result<WxPayUnifiedOrderResult> create(OrderCreateRequest request) {
        String payChannel = request.getPayChannel();
        Long starts = System.currentTimeMillis();
        int random=new Random().nextInt(1000000)+1;//为变量赋随机值1-99999999;
        //传给微信那边的订单号
        String wx_orderSn = "PG"+starts+random;
        DecimalFormat df = new DecimalFormat("0.00");
        PayOrder payOrder = new PayOrder();
        payOrder.setOutTradeNo(request.getOrderSn());
        payOrder.setProductId(wx_orderSn);//唯一的微信订单号
        payOrder.setSubject(request.getSubject());
        payOrder.setBody(request.getBody());
        payOrder.setPayAmount(df.format(Double.parseDouble(request.getPayAmount())));
        payOrder.setPayChannel(payChannel);
        payOrder.setOrderType(request.getOrderType());
        payOrder.setStatus((byte) 0); // 支付状态,0-生成支付订单,1-支付成功,2-退款成功，3-订单关闭，4-业务处理完成
        switch (payChannel) {
            case "WXPAY_NATIVE":
                return Result.success(1,wx_orderSn,wxPayOrderCreate(payOrder));
            case "WXPAY_WAP":
                return null;
            default:
                return Result.error(-1, "不支持此支付方式");
        }
    }

    /**
     * 根据订单编号查询微信订单
     * */
    @Override
    public Result<WxPayOrderQueryResult> query(OrderQueryRequest request) {
        PayOrderExample example = new PayOrderExample();
        PayOrderExample.Criteria c = example.createCriteria();
        c.andOutTradeNoEqualTo(request.getOutTradeNo());
        List<PayOrder> list = payOrderMapper.selectByExample(example);
        if (list.isEmpty()) {
            return Result.error(-1,"没有查到订单信息") ;
        }
        PayOrder payOrder = list.get(0);
        WxPayInfo wxPayInfo = getWxPayInfo(payOrder.getPayChannel());
        if(ObjectUtils.isEmpty(wxPayInfo)){
            return Result.error(-1,"支付渠道错误,该订单支付渠道为：" + payOrder.getPayChannel());
        }
        WxPayService wxPayService = initWxPayService(wxPayInfo.getAppId(),wxPayInfo.getMchId(),wxPayInfo.getMahKey(),wxPayInfo.getCertLocalPath());
        try {
            WxPayOrderQueryResult result = wxPayService.queryOrder("", payOrder.getOutTradeNo());
            return Result.success(1,"订单查询",result);
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        return Result.error(-1, "操作失败");
    }


    @Override
    public Result<WxPayOrderCloseResult> close(OrderCloseRequest request) {
        PayOrderExample example = new PayOrderExample();
        PayOrderExample.Criteria c = example.createCriteria();
        c.andOutTradeNoEqualTo(request.getOutTradeNo());
        List<PayOrder> list = payOrderMapper.selectByExample(example);
        if (list.isEmpty()) {
            return Result.error(-1,"没有查到订单信息") ;
        }
        PayOrder payOrder = list.get(0);
        System.out.println("订单关闭...");
        WxPayInfo wxPayInfo = getWxPayInfo(payOrder.getPayChannel());
        if(ObjectUtils.isEmpty(wxPayInfo)){
            return Result.error(-1,"支付渠道错误,该订单支付渠道为：" + payOrder.getPayChannel());
        }
        WxPayService wxPayService = initWxPayService(wxPayInfo.getAppId(),wxPayInfo.getMchId(),wxPayInfo.getMahKey(),wxPayInfo.getCertLocalPath());
        try {
            WxPayOrderCloseResult result = wxPayService.closeOrder(payOrder.getOutTradeNo());
            return Result.success(1,"订单关闭",result);
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        return Result.error(-1, "操作失败");
    }


    @Override
    public Result<WxPayRefundResult> refund(OrderRefundRequest request) {
        PayOrderExample example = new PayOrderExample();
        PayOrderExample.Criteria c = example.createCriteria();
        c.andOutTradeNoEqualTo(request.getOutTradeNo());
        List<PayOrder> list = payOrderMapper.selectByExample(example);
        if (list.isEmpty()) {
            return Result.error(-1,"没有查到订单信息") ;
        }

        PayOrder payOrder = list.get(0);


        System.out.println("退款...");


        WxPayInfo wxPayInfo = getWxPayInfo(payOrder.getPayChannel());

        if(ObjectUtils.isEmpty(wxPayInfo)){
            return Result.error(-1,"支付渠道错误,该订单支付渠道为：" + payOrder.getPayChannel());
        }

        WxPayService wxPayService = initWxPayService(wxPayInfo.getAppId(),wxPayInfo.getMchId(),wxPayInfo.getMahKey(),wxPayInfo.getCertLocalPath());

        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutRefundNo(request.getOutRefundNo());
        wxPayRefundRequest.setOutTradeNo(request.getOutTradeNo());
        wxPayRefundRequest.setRefundAccount("REFUND_SOURCE_UNSETTLED_FUNDS");
        wxPayRefundRequest.setRefundDesc(request.getRefundReason());
        wxPayRefundRequest.setRefundFee(Math.toIntExact(request.getRefundAmount()));
        wxPayRefundRequest.setTotalFee(Math.toIntExact(request.getPayAmount()));
        wxPayRefundRequest.setNotifyUrl("xxxxx"); //TODO


        try {
            WxPayRefundResult result = wxPayService.refund(wxPayRefundRequest);
            return Result.success(1,"退款",result);
        } catch (WxPayException e) {
            e.printStackTrace();
        }

        return Result.error(-1, "操作失败");
    }

    @Override
    public Result<WxPayRefundQueryResult> refundQuery(RefundQueryRequest request) {
        PayOrderExample example = new PayOrderExample();
        PayOrderExample.Criteria c = example.createCriteria();
        c.andOutTradeNoEqualTo(request.getOutTradeNo());
        List<PayOrder> list = payOrderMapper.selectByExample(example);
        if (list.isEmpty()) {
            return Result.error(-1,"没有查到订单信息") ;
        }

        PayOrder payOrder = list.get(0);


        System.out.println("退款查询...");


        WxPayInfo wxPayInfo = getWxPayInfo(payOrder.getPayChannel());

        if(ObjectUtils.isEmpty(wxPayInfo)){
            return Result.error(-1,"支付渠道错误,该订单支付渠道为：" + payOrder.getPayChannel());
        }

        WxPayService wxPayService = initWxPayService(wxPayInfo.getAppId(),wxPayInfo.getMchId(),wxPayInfo.getMahKey(),wxPayInfo.getCertLocalPath());

        try {
            WxPayRefundQueryResult result = wxPayService.refundQuery(null, request.getOutTradeNo(), null, null);
            return Result.success(1,"退款查询",result);
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        return Result.error(-1, "操作失败");
    }

    private WxPayUnifiedOrderResult wxPayOrderCreate(PayOrder payOrder) {
        //配置微信支付秘钥
        WxPayService wxPayService = initWxPayService(
                CommonConstant.WX_APPID,CommonConstant.WX_MCHID,CommonConstant.WX_APP_SECRET,CommonConstant.WX_ZHENGSHU
        );
//        System.out.println("微信支付证书路劲1===="+CommonConstant.WX_ZHENGSHU);
        int money = (int)Math.ceil(Double.parseDouble(payOrder.getPayAmount()) * 100);
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setTradeType("NATIVE");
        wxPayUnifiedOrderRequest.setOutTradeNo(payOrder.getProductId());
        wxPayUnifiedOrderRequest.setBody(payOrder.getBody());
        wxPayUnifiedOrderRequest.setProductId(payOrder.getOutTradeNo());
        wxPayUnifiedOrderRequest.setTotalFee(money);//传入金额
        wxPayUnifiedOrderRequest.setSpbillCreateIp("1.1.1.1");
        wxPayUnifiedOrderRequest.setNotifyUrl(CommonConstant.WX_NOTIFY_URL);  //TODO 回调方法
        try {
//            System.out.println("微信支付1===="+wxPayUnifiedOrderRequest.getTotalFee());
            //添加到微信订单数据库中
            WxOrderStatus wxOrderStatus = new WxOrderStatus();
            wxOrderStatus.setOrderSn(payOrder.getOutTradeNo());
            wxOrderStatus.setOutTradeNo(payOrder.getProductId());
            wxOrderStatus.setStatus(0);
            wxOrderStatus.setOrderType(Integer.parseInt(payOrder.getOrderType()));
            wxOrderStatus.setRemark("微信订单支付");
            logicMapper.add_wxorderinfo(wxOrderStatus);
            WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
            return wxPayUnifiedOrderResult;
        } catch (WxPayException e) {
            e.printStackTrace();
            System.out.println("微信支付失败=="+e.toString());
            return null;
        }
    }


    private WxPayInfo getWxPayInfo(String payChannel) {

        WxPayInfoExample example = new WxPayInfoExample();
        WxPayInfoExample.Criteria c = example.createCriteria();
        c.andPayChannelEqualTo(payChannel);
        List<WxPayInfo> list = wxPayInfoMapper.selectByExample(example);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    private WxPayService initWxPayService(String appId, String mchId, String mahKey, String certLocalPath) {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(appId);
        payConfig.setMchId(mchId);
        payConfig.setMchKey(mahKey);
        payConfig.setKeyPath(certLocalPath);
        payConfig.setUseSandboxEnv(false); //不使用沙箱环境
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return  wxPayService;
    }

    private void savePayOrder(PayOrder payOrder) {

        payOrderMapper.insertSelective(payOrder);
    }

}
